function RFW.SpawnRailtrail(x, y, z, args, _, step)
	local p = args[1]
	local angle = args[2]
	local aim = args[3]
	local rail = P_SpawnMobj(x, y, z, MT_RAILTRAIL)
	if RFW.restrictsecondcolor.value == 1 and gametyperules & GTR_TEAMS then
		rail.color = ((p.ctfteam == 1) and skincolor_redteam) or ((p.ctfteam == 2) and skincolor_blueteam) or p.secondcolor
	else
		rail.color = p.secondcolor
	end
	if step % 4 then return end //not divisible by 4
	local lstep = step/4
	local rstep = lstep%8+1 //spiral math... how fun...
	local theta = ((44*FU/7)/8)*rstep
	local deg = FixedDiv(180*FU, 22*FU/7)
	local thetdeg = FixedMul(theta,deg)
	local f = P_MobjFlip(p.mo)
	local xo = (FixedMul(cos(FixedAngle(thetdeg)), -sin(angle))+FixedMul(sin(FixedAngle(thetdeg)), FixedMul(-sin(aim), cos(angle))))*12
	local yo = (FixedMul(cos(FixedAngle(thetdeg)), cos(angle))+FixedMul(sin(FixedAngle(thetdeg)), FixedMul(-sin(aim), sin(angle))))*12
	local zo = FixedMul(sin(FixedAngle(thetdeg)), cos(aim))*12*f
	local orb = P_SpawnMobj(x+xo, y+yo, z+zo, MT_RAILTRAIL)
	if RFW.restrictsecondcolor.value == 1 and gametyperules & GTR_TEAMS then
		orb.color = SKINCOLOR_WHITE
	elseif gametyperules & GTR_TEAMS then
		orb.color = ((p.ctfteam == 1) and skincolor_redteam) or ((p.ctfteam == 2) and skincolor_blueteam) or p.railcolor
	else
		orb.color = p.railcolor
	end
end

local function search(table, tlen, str)
	for i = 1, tlen
		--print(table[i].name.." =?= "..str)
		if string.lower(table[i].name) == string.lower(str or "")
			--print("match")
			return i
		end
	end
end

COM_AddCommand("railcolor", function(p, railcolor) //based on cosmetics hatcolor command, thanks to krabs
	local foundcolor = search(skincolors, #skincolors - 1, railcolor)
	if foundcolor then
		railcolor = foundcolor
	else
		railcolor = tonumber($)
	end
	if railcolor == nil or railcolor < 0 or railcolor > #skincolors - 1
		CONS_Printf(p, "Invalid Rail Color!")
		return
	end
	p.railcolor = railcolor
end)

COM_AddCommand("railcolor2", function(p, railcolor) //dont discriminate again splitscreen players!
	local foundcolor = search(skincolors, #skincolors - 1, railcolor)
	if foundcolor then
		railcolor = foundcolor
	else
		railcolor = tonumber($)
	end
	if railcolor == nil or railcolor < 0 or railcolor > #skincolors - 1
		CONS_Printf(p, "Invalid Rail Color!")
		return
	end
	p.railcolor = railcolor
end, COM_SPLITSCREEN)

addHook("PlayerThink", function(p) //failsafe for if railcolor is nil
	if p.railcolor == nil or p.railcolor == SKINCOLOR_NONE then
		p.railcolor = SKINCOLOR_WHITE //or SKINCOLOR_BLUE //use prefered skin color over actual skincolor
	end
end)